﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using StudentEFConsoleApp.EntityFramework.ExtensionMethods;

using System.Data.Entity;
using SchoolPOCOProxyDAL;
using SchoolPOCOProxyDAL.POCOProxyEntities;

namespace StudentEFConsoleApp
{
   public class POCOProxyInConnectedScenario
    {
        public static void AddDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                Student student = new Student();
                student.StudentName = "POCOProxyInConnectedScenario Student1";

                Standard std = new Standard();
                std.StandardName = "POCOProxyInConnectedScenario Standard1";

                student.Standard = std;

                ctx.Students.AddObject(student);
                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario AddDemo successfull");
            }
        }

        public static void AddOneToOneDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                Student student = new Student();
                student.StudentName = "POCOProxyInConnectedScenario Student2";

                Standard std = new Standard();
                std.StandardName = "POCOProxyInConnectedScenario Standard2";

                student.Standard = std;

                StudentAddress sAddress = new StudentAddress();

                sAddress.Address1 = "Address1";
                sAddress.Address2 = "Address2";
                sAddress.City = "City1";
                sAddress.State = "State1";

                student.StudentAddress = sAddress;

                ctx.Students.AddObject(student);
                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario AddOneToOneDemo Successfull");
            }
        }

        //Adding many teachers for one standard
        public static void AddOneToManyDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                Standard std = new Standard();

                std.StandardName = "POCOProxyInConnectedScenario standard3";
                std.Description = "Demo std";

                Teacher teacher1 = new Teacher();
                teacher1.TeacherName = "POCOProxyInConnectedScenario Teacher1";

                Teacher teacher2 = new Teacher();
                teacher2.TeacherName = "POCOProxyInConnectedScenario Teacher2";

                Teacher teacher3 = new Teacher();
                teacher3.TeacherName = "POCOProxyInConnectedScenario Teacher3";


                //Adding many teachers for one standard
                std.Teachers.Add(teacher1);
                std.Teachers.Add(teacher2);
                std.Teachers.Add(teacher3);


                ctx.Standards.AddObject(std);
                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario AddOneToManyDemo Successfull");
            }
        }


        public static void AddManyToManyDemo()
        {

            using (SchoolDBContext ctx = new SchoolDBContext())
            {

                Student student = new Student();
                student.StudentName = "POCOProxyInConnectedScenario Student3";

                Standard std = new Standard();
                std.StandardName = "POCOProxyInConnectedScenario standard4";
                std.Description = "Demo standard";

                student.Standard = std;

                Course course1 = new Course();
                course1.CourseName = "POCOProxyInConnectedScenario Course1";
                course1.Location = "City1";

                Course course2 = new Course();
                course2.CourseName = "POCOProxyInConnectedScenario Course2";
                course2.Location = "City2";

                Course course3 = new Course();
                course3.CourseName = "POCOProxyInConnectedScenario Course3";
                course3.Location = "City1";

                Teacher teacher1 = new Teacher();
                teacher1.TeacherName = "POCOProxyInConnectedScenario teacher1";
                teacher1.Standard = std;

                //assign teacher1 for each courses
                course1.Teacher = teacher1;
                course2.Teacher = teacher1;
                course3.Teacher = teacher1;

                if (student.Courses == null)
                    student.Courses = new List<Course>();

                //Add courses to student
                student.Courses.Add(course1);
                student.Courses.Add(course2);
                student.Courses.Add(course3);

                ctx.Students.AddObject(student);
                ctx.SaveChanges();
            
            }

            Console.WriteLine("POCOProxyInConnectedScenario AddManyToManyDemo Successfull");

        }


        public static void UpdateDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {

                var stud = (from s in ctx.Students
                            where s.StudentName == "POCOProxyInConnectedScenario Student1"
                            select s).FirstOrDefault();

                stud.StudentName = "Updated POCOProxyInConnectedScenario Student1";

                int num = ctx.SaveChanges();
            }

            Console.WriteLine("POCOProxyInConnectedScenario UpdateDemo successfull");

        }


        public static void UpdateOneToOneDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                Student student = (from s in ctx.Students
                                   where s.StudentName == "POCOProxyInConnectedScenario Student2"
                                   select s).FirstOrDefault<Student>();



                student.StudentName = "Updated POCOProxyInConnectedScenario Student2"; 

                StudentAddress sAddress = student.StudentAddress;

                sAddress.Address1 = "Address2";
                sAddress.Address2 = "Address2";
                sAddress.City = "City2";
                sAddress.State = "State2";

                student.StudentAddress = sAddress;

                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario UpdateOneToOneDemo Successfull");
            }
        }

       //Updates Standard name and add one more teacher and removing one existing teacher from that standard 
       //thus teachers of that standard will be updated.
        public static void UpdateOneToManyDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {

                //fetching existing standard from the db
                Standard std = (from s in ctx.Standards
                                where s.StandardName == "POCOProxyInConnectedScenario standard3"
                                select s).FirstOrDefault<Standard>();

                std.StandardName = "Updated POCOProxyInConnectedScenario standard3";
                std.Description = "Updated standard";

                //getting first teacher to be removed
                Teacher tchr = std.Teachers.FirstOrDefault<Teacher>();
                //removing teachers (enable cascading delete for the teacher)
                if (tchr != null)
                    ctx.Teachers.DeleteObject(tchr);

                //Do not use std.Teachers.Remove(tchr). It will give exception. 
                //This statement doesn't remove teacher from teachers collection but it trying to remove relationship.
                //std.Teachers.Remove(tchr);
                
                 Teacher newTeacher = new Teacher();
                 newTeacher.TeacherName = "POCOProxyInConnectedScenario New Teacher";

                std.Teachers.Add(newTeacher);

                Teacher existingTeacher = (from t in ctx.Teachers
                                           where t.StandardId != std.StandardId
                                           select t).FirstOrDefault<Teacher>();

                std.Teachers.Add(existingTeacher);

                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario UpdateOneToManyDemo Successfull");
            }
        }


       //removes one course from student's course lists
        public static void UpdateManyToManyDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {

                Student student = (from s in ctx.Students
                                   where s.StudentName == "POCOProxyInConnectedScenario Student3"
                                   select s).FirstOrDefault<Student>();


                student.StudentName = "Updated POCOProxyInConnectedScenario Student3";

                Course cours = student.Courses.FirstOrDefault<Course>();

                //removing course from student
                student.Courses.Remove(cours);

                ctx.SaveChanges();
            }

            Console.WriteLine("POCOProxyInConnectedScenario UpdateManyToManyDemo Successfull");
        }

        public static void DeleteDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                var stud = (from s in ctx.Students
                            where s.StudentName == "Updated POCOProxyInConnectedScenario Student1"
                            select s).FirstOrDefault();

                ctx.Students.DeleteObject(stud);

                int num = ctx.SaveChanges();
            }
            Console.WriteLine("POCOProxyInConnectedScenario DeleteDemo successfull");
        }

       

        public static void DeleteOneToOneDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                Student student = (from s in ctx.Students
                                   where s.StudentName == "Updated POCOProxyInConnectedScenario Student2"
                                   select s).FirstOrDefault<Student>();



                StudentAddress sAddress = student.StudentAddress;

                ctx.StudentAddresses.DeleteObject(sAddress);

                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario DeleteOneToOneDemo Successfull");
            }
        }

        public static void DeleteOneToManyDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {
                //fetching existing standard from the db
                Standard std = (from s in ctx.Standards
                                where s.StandardName == "Updated POCOProxyInConnectedScenario standard3"
                                select s).FirstOrDefault<Standard>();

                
                //getting first teacher to be removed
                Teacher tchr = std.Teachers.FirstOrDefault<Teacher>();
                //removing teachers 
                if (tchr != null)
                    ctx.Teachers.DeleteObject(tchr);

                //Do not use std.Teachers.Remove(tchr). It will give exception. 
                //This statement doesn't remove teacher from teachers collection but it trying to remove relationship.
                //std.Teachers.Remove(tchr);

                ctx.SaveChanges();

                Console.WriteLine("POCOProxyInConnectedScenario DeleteOneToManyDemo Successfull");
            }
        }

        //removes one course from student's course lists: same as update
        public static void DeleteManyToManyDemo()
        {
            using (SchoolDBContext ctx = new SchoolDBContext())
            {

                Student student = (from s in ctx.Students
                                   where s.StudentName == "Updated POCOProxyInConnectedScenario Student3"
                                   select s).FirstOrDefault<Student>();


                Course cours = student.Courses.FirstOrDefault<Course>();

                //removing course from student
                student.Courses.Remove(cours);

                ctx.SaveChanges();
            }

            Console.WriteLine("POCOProxyInConnectedScenario DeleteManyToManyDemo Successfull");
        }
    }
}
